package pcvc.server;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import pcvc.common.classes.Question;

import net.java.dev.eval.Equation;
import net.java.dev.eval.Expression;
import net.java.dev.eval.IEquation;

/**
 * @author SEBASTIAN
 * @version 1.0
 * @created 26-nov-2013 06:43:26 p.m.
 */
public class PCVCCalculator
{

    private static final String ASSIGNMENT_PATTERN = "^\\s*(\\p{Alpha}[\\p{Alnum}_]*)\\s*=([^=].*)$";
    private Map vars;

    private static PCVCCalculator calculatorInstance;

    public static PCVCCalculator getInstance( )
    {
        if( calculatorInstance == null )
        {
            synchronized( PCVCCalculator.class )
            {
                if( calculatorInstance == null )
                {
                    calculatorInstance = new PCVCCalculator( );
                }
            }
        }

        return calculatorInstance;
    }

    /**
     * 
     * @param str0
     */
    public BigDecimal evaluator( String str0, Map<String, String> variables )
    {

        vars = variables;

        final Pattern assignmentPattern = Pattern.compile( ASSIGNMENT_PATTERN );

        final Matcher assignmentMatcher = assignmentPattern.matcher( str0 );

        if( assignmentMatcher.find( ) )
        {
            String variableName = assignmentMatcher.group( 1 );

            String expression = assignmentMatcher.group( 2 );

            BigDecimal result;

            try
            {
                Equation equation = new Equation( expression );
                result = equation.eval( vars );
                vars.put( variableName, expression );

                return result;
            }
            catch( RuntimeException e )
            {
                return null;
            }

        }
        else if( str0.startsWith( "'" ) )
        {
            return null;

        }

        return null;
    }

    public BigDecimal evaluateQuestion( Question question )
    {
        BigDecimal resp = new BigDecimal( 0 );

        Map<String, Expression> variables = new LinkedHashMap<String, Expression>( );

        Iterator<Entry<String, String>> iterator = question.getVariables( ).entrySet( ).iterator( );

        while( iterator.hasNext( ) )
        {
            Entry<String, String> entry = iterator.next( );
            IEquation equation = new Equation( entry.getValue( ) );
            variables.put( entry.getKey( ), equation.getRootExpression( ) );
        }
        
        Pattern assignmentPattern = Pattern.compile( ASSIGNMENT_PATTERN );
        Matcher assignmentMatcher = assignmentPattern.matcher( question.getEquation( ) );
        
        if(assignmentMatcher.find( ))
        {
            String variableName = assignmentMatcher.group(1 );
            String expr = assignmentMatcher.group( 2 );
            IEquation equation = new Equation( expr );
            variables.put( variableName, equation.getRootExpression( ) );
            
            
            IEquation equationSolved = new Equation( variableName );
            resp = equationSolved.eval( variables );
        }        

        return resp;
    }
    
}// end PCVCCalculator